#coding=utf-8
"""
头太晕
torrycn@gmail.com
"""
import os
import sys
import socket
from StringIO import StringIO
import conf
import time


META_NAMES = ('APPL_MD_PATH',
    'APPL_PHYSICAL_PATH',
    'AUTH_PASSWORD',
    'AUTH_TYPE',
    'AUTH_USER',
    'CERT_COOKIE',
    'CERT_FLAGS',
    'CERT_ISSUER',
    'CERT_KEYSIZE',
    'CERT_SECRETKEYSIZE',
    'CERT_SERIALNUMBER',
    'CERT_SERVER_ISSUER',
    'CERT_SERVER_SUBJECT',
    'CERT_SUBJECT',
    'CONTENT_LENGTH',
    'CONTENT_TYPE',
    'GATEWAY_INTERFACE',
    'HTTPS',
    'HTTPS_KEYSIZE',
    'HTTPS_SECRETKEYSIZE',
    'HTTPS_SERVER_ISSUER',
    'HTTPS_SERVER_SUBJECT',
    'INSTANCE_ID',
    'INSTANCE_META_PATH',
    'LOCAL_ADDR',
    'LOGON_USER',
    'PATH_INFO',
    'PATH_TRANSLATED',
    'QUERY_STRING',
    'REMOTE_ADDR',
    'REMOTE_HOST',
    'REMOTE_USER',
    'REQUEST_METHOD',
    'SERVER_NAME',
    'SCRIPT_NAME',
    'SERVER_PORT',
    'SERVER_PORT_SECURE',
    'SERVER_PROTOCOL',
    'SERVER_SOFTWARE',
    'URL',
    'HTTP_CONNECTION',
    'HTTP_ACCEPT',
    'HTTP_ACCEPT_ENCODING',
    'HTTP_ACCEPT_LANGUAGE',
    'HTTP_COOKIE',
    'HTTP_HOST',
    'HTTP_USER_AGENT',
    'HTTP_UA_CPU',)

STATUS_CODE_TEXT={100:'CONTINUE',
    101: 'SWITCHING PROTOCOLS',
    200: 'OK',
    201: 'CREATED',
    202: 'ACCEPTED',
    203: 'NON-AUTHORITATIVE INFORMATION',
    204: 'NO CONTENT',
    205: 'RESET CONTENT',
    206: 'PARTIAL CONTENT',
    300: 'MULTIPLE CHOICES',
    301: 'MOVED PERMANENTLY',
    302: 'FOUND',
    303: 'SEE OTHER',
    304: 'NOT MODIFIED',
    305: 'USE PROXY',
    306: 'RESERVED',
    307: 'TEMPORARY REDIRECT',
    400: 'BAD REQUEST',
    401: 'UNAUTHORIZED',
    402: 'PAYMENT REQUIRED',
    403: 'FORBIDDEN',
    404: 'NOT FOUND',
    405: 'METHOD NOT ALLOWED',
    406: 'NOT ACCEPTABLE',
    407: 'PROXY AUTHENTICATION REQUIRED',
    408: 'REQUEST TIMEOUT',
    409: 'CONFLICT',
    410: 'GONE',
    411: 'LENGTH REQUIRED',
    412: 'PRECONDITION FAILED',
    413: 'REQUEST ENTITY TOO LARGE',
    414: 'REQUEST-URI TOO LONG',
    415: 'UNSUPPORTED MEDIA TYPE',
    416: 'REQUESTED RANGE NOT SATISFIABLE',
    417: 'EXPECTATION FAILED',
    500: 'INTERNAL SERVER ERROR',
    501: 'NOT IMPLEMENTED',
    502: 'BAD GATEWAY',
    503: 'SERVICE UNAVAILABLE',
    504: 'GATEWAY TIMEOUT',
    505: 'HTTP VERSION NOT SUPPORTED',}


SITES = {}


def handler(ecb):
    global SITES
    try:
        import mimetools
        path = ecb.GetServerVariable('APPL_PHYSICAL_PATH')
        site = SITES.get(path,None)
        if site is None:
            site = conf.get(path)
            SITES[path] = site
        sck = createSCGISocket(site)
    except Exception,e:
        ecb.SendResponseHeaders('500 INTERNAL SERVER ERROR','\r\n',False)
        print >> ecb,str(e)
        ecb.DoneWithSession()
        return
    requestData = createSCGIHeaders(ecb,site)
    requestData = '%d:%s,' % (len(requestData),requestData)
    sck.send(requestData)
    if(ecb.AvailableBytes > 0):
        sck.send(ecb.AvailableData)
    buffer = StringIO()
    try:
        while True:
            buf = sck.recv(8192)
            if len(buf) == 0:
                break
            buffer.write(buf)
    except:
        pass
    sck.close()
    buffer.pos = 0
    responseHeaders = StringIO()
    status = ''
    line = buffer.readline()
    while line != '':
        if line.lower().startswith("status"):
            status = line[:-2].split(':',1)[-1]
        else:
            responseHeaders.write(line)
        line = buffer.readline()
        if line == '\r\n':
            responseHeaders.write(line)
            break
    responseHeaders.pos = 0
    ecb.SendResponseHeaders(status,responseHeaders.read(),False)
    ecb.write(buffer.read())
    buffer.close()
    ecb.DoneWithSession()


def terminate():
    global SITES
    SITES.clear()


def createSCGIHeaders(ecb,config):
    env = {}#dict(os.environ)
    for k in META_NAMES:
        try:
            env[k] = ecb.GetServerVariable(k)
        except:
            pass
    env["SCGI"] = "1"
    env["ONTENT_LENGTH"] = env.get("ONTENT_LENGTH","0")
    if config.use_webserver_script_name:
        env["SCRIPT_NAME"] = env.get("SCRIPT_NAME",'/')[1:]
    else:
        env["SCRIPT_NAME"] = config.script_name
    if config.gb2utf8:
        env['PATH_INFO'] = unicode(env['PATH_INFO'],'gb2312').encode('utf-8')
    return ''.join(['%s\x00%s\x00' % (k,v) for k,v in env.items()])


def createSCGISocket(site):
    sck = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    try:
        sck.connect(('127.0.0.1',site.port))
    except:
        raise Exception('Can not connect the scgi process')
    return sck


